﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using Kiiro.Model;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using System.IO;
using System.Collections.Generic;

namespace Kiiro.WebServices
{

    [Serializable]
    public class KiiroDocumentStatusFlags
    {
        public bool ProjectDoesNotExist = false;
        public bool UserDoesNotExist = false;
        public bool SessionDoesNotExist = false;
        public bool ExceptionOccurred = false;
        public string Exception;
        public bool Success = false;
    }

    /// <summary>
    /// Summary description for KiiroDiscussion
    /// </summary>
    [WebService(Namespace = "http://mykiiro.com/document")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class KiiroDocument : System.Web.Services.WebService
    {

        private const string SessionFolder = "WebServiceDocumentSessions";

        [WebMethod]
        public void AddDocumentToLibrary(string projectSiteName, string documentSessionKey, string finalFileName, int createdBySPUserID, DateTime createdDate, out KiiroDocumentStatusFlags status)
        {
            Guid siteCollectionId;
            string serverRelativeUrl = null;
            status = new KiiroDocumentStatusFlags();            
            status.Success = true;            
            Document document = null;
            User createdBy = null;

            try
            {
                //try and get the site collection ID and relative URL
                SPHelpers.GetSiteCollectionIdAndServerRelativeUrl(Context.Request.Url.Scheme + "://" + Context.Request.Url.Authority + Context.Request.RawUrl, out siteCollectionId, out serverRelativeUrl);

                //check that the project url does not already exist                
                if (!WebServicesHelper.DoesProjectExist(projectSiteName, siteCollectionId, serverRelativeUrl))
                {
                    status.ProjectDoesNotExist = true;
                    status.Success = false;
                }
                else
                {
                    //read in the file
                    byte[] fileContents = ReadSessionFile(documentSessionKey);

                    //delete the session file
                    DeleteSessionFile(documentSessionKey);

                    //add the document to the library
                    document = new Document();
                    createdBy = UserModel.GetOrCreateUser(createdBySPUserID, siteCollectionId, serverRelativeUrl + "/" + projectSiteName);

                    document.Title = finalFileName;
                    document.CreatedBy = createdBy;
                    document.CreatedDate = createdDate;
                    document.ModifiedBy = createdBy;
                    document.ModifiedDate = createdDate;
                    document.FileBytes = fileContents;
                    document.FileLength = fileContents.Length;
                    document.EditType = EditType.Created;
                    document.SiteCollectionId = siteCollectionId;
                    document.IsFolder = false;
                    document.FolderUrl = serverRelativeUrl + "/" + projectSiteName + Constants.SPListUrls.Documents;


                    
                    DocumentModel.Save(document,new List<int>(),createdBy, siteCollectionId,  serverRelativeUrl + "/" + projectSiteName);

                    //grab the latest activity for the project and update the matching activity history dates. When the doc
                    //is added through the DAL, the Created and Modified properties of doc.item are not set correctly and therefore
                    //the activity is always created at today's date and time
                    List<ActivityHistory> historyList = ActivityHistoryModel.GetActivity(
                        siteCollectionId, serverRelativeUrl + "/" + projectSiteName, ItemType.All, createdBy, 5, 0);
                    foreach (ActivityHistory history in historyList)
                    {
                        if ("/" + history.ActivityReferenceUrl == Constants.SPListUrls.Documents + "/" + document.Title)
                        {
                            history.CreatedDate = document.CreatedDate;
                            history.ModifiedDate = document.ModifiedDate;
                            history.EditType = EditType.Updated;
                         
                            ActivityHistoryModel.Save(history, siteCollectionId, serverRelativeUrl + "/" + projectSiteName);
                            break;
                        }
                    }
                    
                }
            }
            catch (Exception ex)
            {
                status.ExceptionOccurred = true;
                status.Exception = ex.ToString();
                status.Success = false;
            }

        }

       

        private string BeginDocumentTransferSession()
        {

            
            string sessionKey = "";

            sessionKey = Guid.NewGuid().ToString();

            //create a new file for the session
            SetupSessionDirectory();

            FileStream file = File.Create(Server.MapPath(SessionFolder + "/" + sessionKey));
            file.Close();
 

            return (sessionKey);
            
        }
        
        internal void DeleteSessionFile(string sessionKey)
        {
            if (File.Exists(Server.MapPath(SessionFolder + "/" + sessionKey)))
                File.Delete(Server.MapPath(SessionFolder + "/" + sessionKey));
        }


        internal byte[] ReadSessionFile(string sessionKey)
        {
            FileStream file = File.Open(Server.MapPath(SessionFolder + "/" + sessionKey), FileMode.Open, FileAccess.Read,FileShare.Read);

            byte[] fileContents = new byte[file.Length];

            file.Read(fileContents, 0, (int)file.Length);

            file.Close();

            return fileContents;
        }


        [WebMethod]
        public void TransferDocumentChunk(ref string sessionKey, byte[] documentChunk, out KiiroDocumentStatusFlags status)
        {

            status = new KiiroDocumentStatusFlags();

            try
            {

                if (sessionKey == null || sessionKey == "")
                    sessionKey = BeginDocumentTransferSession();
                else if (!File.Exists(Server.MapPath(SessionFolder + "/" + sessionKey)))
                    status.SessionDoesNotExist = true;

                if (!status.SessionDoesNotExist)
                {
                    FileStream file = File.Open(Server.MapPath(SessionFolder + "/" + sessionKey), FileMode.Append, FileAccess.Write, FileShare.None);
                    file.Write(documentChunk, 0, documentChunk.Length);
                    file.Close();
                    status.Success = true;
                }
                
            }
            catch (Exception ex)
            {
                status.ExceptionOccurred = true;
                status.Exception = ex.ToString();
            }

        }

        private void SetupSessionDirectory()
        {
            //create a local folder to store files in
            if (!Directory.Exists(Server.MapPath(SessionFolder)))
                Directory.CreateDirectory(Server.MapPath(SessionFolder));
        }
    }


}
